{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Tce3stUlHN0L"
      },
      "source": [
        "##### Copyright 2024 Google LLC."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 62,
      "metadata": {
        "cellView": "form",
        "id": "tuOe1ymfHZPu"
      },
      "outputs": [],
      "source": [
        "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yeadDkMiISin"
      },
      "source": [
        "# Get started with the Gemini API: Python"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lEXQ3OwKIa-O"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://ai.google.dev/gemini-api/docs/get-started/python\"><img src=\"https://ai.google.dev/static/site-assets/images/docs/notebook-site-button.png\" height=\"32\" width=\"32\" />View on Google AI</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/google/generative-ai-docs/blob/main/site/en/gemini-api/docs/get-started/python.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/google/generative-ai-docs/blob/main/site/en/gemini-api/docs/get-started/python.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uOxMUKTxR-_j"
      },
      "source": [
        "This quickstart demonstrates how to use the Python SDK for the Gemini API, which gives you access to Google's Gemini large language models. In this quickstart, you will learn how to:\n",
        "\n",
        "1. Set up your development environment and API access to use Gemini.\n",
        "2. Generate text responses from text inputs.\n",
        "3. Generate text responses from multimodal inputs (text and images).\n",
        "4. Use Gemini for multi-turn conversations (chat).\n",
        "5. Use embeddings for large language models."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "H9__zr1nSBpE"
      },
      "source": [
        "## Prerequisites\n",
        "\n",
        "You can run this quickstart in [Google Colab](https://colab.research.google.com/github/google/generative-ai-docs/blob/main/site/en/gemini-api/docs/get-started/python.ipynb), which runs this notebook directly in the browser and does not require additional environment configuration.\n",
        "\n",
        "Alternatively, to complete this quickstart locally, ensure that your development environment meets the following requirements:\n",
        "\n",
        "-  Python 3.9+\n",
        "-  An installation of `jupyter` to run the notebook."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FFPBKLapSCkM"
      },
      "source": [
        "## Setup"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wFNV1e3ASJha"
      },
      "source": [
        "### Install the Python SDK\n",
        "\n",
        "The Python SDK for the Gemini API, is contained in the [`google-generativeai`](https://pypi.org/project/google-generativeai/) , **langchain-google-genai**  package. Install the dependency using pip:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "9OEoeosRTv-5",
        "outputId": "e906b072-d67b-4dae-851b-7ca99473de7c",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m165.0/165.0 kB\u001b[0m \u001b[31m3.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m725.4/725.4 kB\u001b[0m \u001b[31m17.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "langchain-google-genai 2.0.0 requires google-generativeai<0.8.0,>=0.7.0, but you have google-generativeai 0.8.1 which is incompatible.\u001b[0m\u001b[31m\n",
            "\u001b[0m"
          ]
        }
      ],
      "source": [
        "!pip install -q -U google-generativeai\n",
        "!pip install -qU langchain-google-genai"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KCFF5VSTbcAR"
      },
      "source": [
        "### Import packages"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vRC2HngneEeQ"
      },
      "source": [
        "Import the necessary packages."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "TS9l5igubpHO"
      },
      "outputs": [],
      "source": [
        "import pathlib\n",
        "import textwrap\n",
        "\n",
        "import google.generativeai as genai\n",
        "\n",
        "from IPython.display import display\n",
        "from IPython.display import Markdown\n",
        "\n",
        "\n",
        "def to_markdown(text):\n",
        "    text = text.replace(\"•\", \"  *\")\n",
        "    return Markdown(textwrap.indent(text, \"> \", predicate=lambda _: True))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "d10c38a5c91f"
      },
      "outputs": [],
      "source": [
        "# Used to securely store your API key\n",
        "from google.colab import userdata"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gHYFrFPjSGNq"
      },
      "source": [
        "### Setup your API key\n",
        "\n",
        "Before you can use the Gemini API, you must first obtain an API key. If you don't already have one, create a key with one click in Google AI Studio.\n",
        "\n",
        "<a class=\"button button-primary\" href=\"https://makersuite.google.com/app/apikey\" target=\"_blank\" rel=\"noopener noreferrer\">Get an API key</a>\n",
        "\n",
        "Note that depending on where you are located, you might have to [enable billing](https://ai.google.dev/gemini-api/docs/billing#enable-cloud-billing) since the free tier is not available in [EEA (including EU), the UK, and CH](https://ai.google.dev/gemini-api/docs/billing#is-Gemini-free-in-EEA-UK-CH)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tHhsUxDTdw0W"
      },
      "source": [
        "In Colab, add the key to the secrets manager under the \"🔑\" in the left panel. Give it the name `GEMINI_API_KEY`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VmSlTHXxb5pV"
      },
      "source": [
        "Once you have the API key, pass it to the SDK. You can do this in two ways:\n",
        "\n",
        "* Put the key in the `GEMINI_API_KEY` environment variable (the SDK will automatically pick it up from there).\n",
        "* Pass the key to `genai.configure(api_key=...)`"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "id": "ab9ASynfcIZn"
      },
      "outputs": [],
      "source": [
        "# Or use `os.getenv('GEMINI_API_KEY')` to fetch an environment variable.\n",
        "GEMINI_API_KEY = userdata.get(\"GEMINI_API_KEY\")\n",
        "\n",
        "# print(GEMINI_API_KEY )\n",
        "\n",
        "genai.configure(api_key=GEMINI_API_KEY)"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_google_genai import  llms\n",
        "list(llms.genai.list_models())"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        },
        "collapsed": true,
        "id": "6qABRn8M8CcS",
        "outputId": "4c7cfba3-9ae6-40ec-90c5-729e285d88cf"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[Model(name='models/chat-bison-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='PaLM 2 Chat (Legacy)',\n",
              "       description='A legacy text-only model optimized for chat conversations',\n",
              "       input_token_limit=4096,\n",
              "       output_token_limit=1024,\n",
              "       supported_generation_methods=['generateMessage', 'countMessageTokens'],\n",
              "       temperature=0.25,\n",
              "       max_temperature=None,\n",
              "       top_p=0.95,\n",
              "       top_k=40),\n",
              " Model(name='models/text-bison-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='PaLM 2 (Legacy)',\n",
              "       description='A legacy model that understands text and generates text as an output',\n",
              "       input_token_limit=8196,\n",
              "       output_token_limit=1024,\n",
              "       supported_generation_methods=['generateText', 'countTextTokens', 'createTunedTextModel'],\n",
              "       temperature=0.7,\n",
              "       max_temperature=None,\n",
              "       top_p=0.95,\n",
              "       top_k=40),\n",
              " Model(name='models/embedding-gecko-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Embedding Gecko',\n",
              "       description='Obtain a distributed representation of a text.',\n",
              "       input_token_limit=1024,\n",
              "       output_token_limit=1,\n",
              "       supported_generation_methods=['embedText', 'countTextTokens'],\n",
              "       temperature=None,\n",
              "       max_temperature=None,\n",
              "       top_p=None,\n",
              "       top_k=None),\n",
              " Model(name='models/gemini-1.0-pro-latest',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.0 Pro Latest',\n",
              "       description=('The best model for scaling across a wide range of tasks. This is the latest '\n",
              "                    'model.'),\n",
              "       input_token_limit=30720,\n",
              "       output_token_limit=2048,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=0.9,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=None),\n",
              " Model(name='models/gemini-1.0-pro',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.0 Pro',\n",
              "       description='The best model for scaling across a wide range of tasks',\n",
              "       input_token_limit=30720,\n",
              "       output_token_limit=2048,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=0.9,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=None),\n",
              " Model(name='models/gemini-pro',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.0 Pro',\n",
              "       description='The best model for scaling across a wide range of tasks',\n",
              "       input_token_limit=30720,\n",
              "       output_token_limit=2048,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=0.9,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=None),\n",
              " Model(name='models/gemini-1.0-pro-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.0 Pro 001 (Tuning)',\n",
              "       description=('The best model for scaling across a wide range of tasks. This is a stable '\n",
              "                    'model that supports tuning.'),\n",
              "       input_token_limit=30720,\n",
              "       output_token_limit=2048,\n",
              "       supported_generation_methods=['generateContent', 'countTokens', 'createTunedModel'],\n",
              "       temperature=0.9,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=None),\n",
              " Model(name='models/gemini-1.0-pro-vision-latest',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.0 Pro Vision',\n",
              "       description='The best image understanding model to handle a broad range of applications',\n",
              "       input_token_limit=12288,\n",
              "       output_token_limit=4096,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=0.4,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=32),\n",
              " Model(name='models/gemini-pro-vision',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.0 Pro Vision',\n",
              "       description='The best image understanding model to handle a broad range of applications',\n",
              "       input_token_limit=12288,\n",
              "       output_token_limit=4096,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=0.4,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=32),\n",
              " Model(name='models/gemini-1.5-pro-latest',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Pro Latest',\n",
              "       description='Mid-size multimodal model that supports up to 2 million tokens',\n",
              "       input_token_limit=2097152,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-pro-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Pro 001',\n",
              "       description='Mid-size multimodal model that supports up to 2 million tokens',\n",
              "       input_token_limit=2097152,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens', 'createCachedContent'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-pro',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Pro',\n",
              "       description='Mid-size multimodal model that supports up to 2 million tokens',\n",
              "       input_token_limit=2097152,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-pro-exp-0801',\n",
              "       base_model_id='',\n",
              "       version='exp-0801',\n",
              "       display_name='Gemini 1.5 Pro Experimental 0801',\n",
              "       description='Mid-size multimodal model that supports up to 2 million tokens',\n",
              "       input_token_limit=2097152,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-pro-exp-0827',\n",
              "       base_model_id='',\n",
              "       version='exp-0827',\n",
              "       display_name='Gemini 1.5 Pro Experimental 0827',\n",
              "       description='Mid-size multimodal model that supports up to 2 million tokens',\n",
              "       input_token_limit=2097152,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-flash-latest',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Flash Latest',\n",
              "       description='Fast and versatile multimodal model for scaling across diverse tasks',\n",
              "       input_token_limit=1048576,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-flash-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Flash 001',\n",
              "       description='Fast and versatile multimodal model for scaling across diverse tasks',\n",
              "       input_token_limit=1048576,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens', 'createCachedContent'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-flash-001-tuning',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Flash 001 Tuning',\n",
              "       description='Fast and versatile multimodal model for scaling across diverse tasks',\n",
              "       input_token_limit=16384,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens', 'createTunedModel'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-flash',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Flash',\n",
              "       description='Fast and versatile multimodal model for scaling across diverse tasks',\n",
              "       input_token_limit=1048576,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-flash-exp-0827',\n",
              "       base_model_id='',\n",
              "       version='exp-0827',\n",
              "       display_name='Gemini 1.5 Flash Experimental 0827',\n",
              "       description='Fast and versatile multimodal model for scaling across diverse tasks',\n",
              "       input_token_limit=1048576,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/gemini-1.5-flash-8b-exp-0827',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Gemini 1.5 Flash 8B Experimental 0827',\n",
              "       description='Fast and versatile multimodal model for scaling across diverse tasks',\n",
              "       input_token_limit=1048576,\n",
              "       output_token_limit=8192,\n",
              "       supported_generation_methods=['generateContent', 'countTokens'],\n",
              "       temperature=1.0,\n",
              "       max_temperature=2.0,\n",
              "       top_p=0.95,\n",
              "       top_k=64),\n",
              " Model(name='models/embedding-001',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Embedding 001',\n",
              "       description='Obtain a distributed representation of a text.',\n",
              "       input_token_limit=2048,\n",
              "       output_token_limit=1,\n",
              "       supported_generation_methods=['embedContent'],\n",
              "       temperature=None,\n",
              "       max_temperature=None,\n",
              "       top_p=None,\n",
              "       top_k=None),\n",
              " Model(name='models/text-embedding-004',\n",
              "       base_model_id='',\n",
              "       version='004',\n",
              "       display_name='Text Embedding 004',\n",
              "       description='Obtain a distributed representation of a text.',\n",
              "       input_token_limit=2048,\n",
              "       output_token_limit=1,\n",
              "       supported_generation_methods=['embedContent'],\n",
              "       temperature=None,\n",
              "       max_temperature=None,\n",
              "       top_p=None,\n",
              "       top_k=None),\n",
              " Model(name='models/aqa',\n",
              "       base_model_id='',\n",
              "       version='001',\n",
              "       display_name='Model that performs Attributed Question Answering.',\n",
              "       description=('Model trained to return answers to questions that are grounded in provided '\n",
              "                    'sources, along with estimating answerable probability.'),\n",
              "       input_token_limit=7168,\n",
              "       output_token_limit=1024,\n",
              "       supported_generation_methods=['generateAnswer'],\n",
              "       temperature=0.2,\n",
              "       max_temperature=None,\n",
              "       top_p=1.0,\n",
              "       top_k=40)]"
            ]
          },
          "metadata": {},
          "execution_count": 16
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8ssbTMNVSMd-"
      },
      "source": [
        "## List models\n",
        "\n",
        "Now you're ready to call the Gemini API. Use `list_models` to see the available Gemini models:\n",
        "\n",
        "* `gemini-1.5-flash`: optimized for multi-modal use-cases where speed and cost are important. This should be your go-to model.\n",
        "* `gemini-1.5-pro`: optimized for high intelligence tasks, the most powerful Gemini model"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "id": "QvvWFy08e5c5",
        "outputId": "dbeacfa9-8e08-44be-f771-8282c47e12c5",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 321
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "models/gemini-1.0-pro-latest\n",
            "models/gemini-1.0-pro\n",
            "models/gemini-pro\n",
            "models/gemini-1.0-pro-001\n",
            "models/gemini-1.0-pro-vision-latest\n",
            "models/gemini-pro-vision\n",
            "models/gemini-1.5-pro-latest\n",
            "models/gemini-1.5-pro-001\n",
            "models/gemini-1.5-pro\n",
            "models/gemini-1.5-pro-exp-0801\n",
            "models/gemini-1.5-pro-exp-0827\n",
            "models/gemini-1.5-flash-latest\n",
            "models/gemini-1.5-flash-001\n",
            "models/gemini-1.5-flash-001-tuning\n",
            "models/gemini-1.5-flash\n",
            "models/gemini-1.5-flash-exp-0827\n",
            "models/gemini-1.5-flash-8b-exp-0827\n"
          ]
        }
      ],
      "source": [
        "for m in llms.genai.list_models():\n",
        "    if \"generateContent\" in m.supported_generation_methods:\n",
        "        print(m.name)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FTl5NjtrhA0J"
      },
      "source": [
        "Note: For detailed information about the available models, including their capabilities and rate limits, see [Gemini models](https://ai.google.dev/models/gemini). There are options for requesting [rate limit increases](https://ai.google.dev/docs/increase_quota). The rate limit for Gemini-Flash models is 15 requests per minute (RPM) for free ([in supported countries](https://ai.google.dev/gemini-api/docs/billing#is-Gemini-free-in-EEA-UK-CH)).\n",
        "\n",
        "The `genai` package also supports the PaLM  family of models, but only the Gemini models support the generic, multimodal capabilities of the `generateContent` method."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LZfoK3I3hu6V"
      },
      "source": [
        "## Generate text from text inputs\n",
        "\n",
        "Always start with the 'gemini-1.5-flash' model. It should be sufficient for most of your tasks:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "2bcfnGEviwTI"
      },
      "outputs": [],
      "source": [
        "from langchain_google_genai import ChatGoogleGenerativeAI\n",
        "\n",
        "model = ChatGoogleGenerativeAI(model=\"gemini-pro\", api_key=GEMINI_API_KEY)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WR_2A_sxk8sK"
      },
      "source": [
        "The `invoke` method can handle a wide variety of use cases, including multi-turn chat and multimodal input, depending on what the underlying model supports. At the moment, the available models support text, images and videos as input, and text as output.\n",
        "\n",
        "In the simplest case, you can pass a prompt string to the <a href=\"https://ai.google.dev/api/generate-content#v1beta.models.generateContent\"><code>GenerativeModel.generate_content</code></a> method:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "id": "he-OfzBbhACQ",
        "outputId": "af783647-4c79-4e72-a98b-9f36638e0b9b",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "CPU times: user 45.1 ms, sys: 7.22 ms, total: 52.4 ms\n",
            "Wall time: 4.73 s\n"
          ]
        }
      ],
      "source": [
        "%%time\n",
        "response = model.invoke(\"What is the meaning of life?\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FbrR-n_qlpFd"
      },
      "source": [
        "In simple cases, the `response.content` accessor is all you need. To display formatted Markdown text, use the `to_markdown` function:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {
        "id": "G-zBkueElVEO",
        "outputId": "a69fed4f-4e06-421d-f322-cde216f310ab",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 300
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ],
            "text/markdown": "> The meaning of life is a philosophical question that has been pondered by humans for centuries. There is no one definitive answer, as the meaning of life is subjective and can vary from person to person. However, there are some common themes that emerge when people discuss the meaning of life, such as:\n> \n> * **Finding purpose:** Many people believe that the meaning of life is to find a purpose or goal that gives them direction and motivation. This purpose can be anything from raising a family to pursuing a career to making a difference in the world.\n> * **Living in the present moment:** Some people believe that the meaning of life is to live in the present moment and appreciate the simple things in life. This means savoring each experience, both good and bad, and not dwelling on the past or worrying about the future.\n> * **Making a difference:** Others believe that the meaning of life is to make a difference in the world. This can be done through acts of kindness, volunteering, or simply being a good person.\n> * **Finding happiness:** Some people believe that the meaning of life is to find happiness. This can be achieved through a variety of means, such as spending time with loved ones, pursuing hobbies, or traveling.\n> \n> Ultimately, the meaning of life is something that each individual must discover for themselves. There is no right or wrong answer, and the meaning of life can change over time as we grow and change. However, by exploring our values, beliefs, and experiences, we can each come to a better understanding of what makes life meaningful to us."
          },
          "metadata": {},
          "execution_count": 22
        }
      ],
      "source": [
        "to_markdown(response.content)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UZPpoKMQoru8"
      },
      "source": [
        "If the API failed to return a result, use `GenerateContentResponse.prompt_feedback` to see if it was blocked due to safety concerns regarding the prompt."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "id": "eIQdU8AGoraT",
        "outputId": "9f012ab8-36eb-4b3a-cd35-3b962c6281b0",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'prompt_feedback': {'block_reason': 0, 'safety_ratings': []},\n",
              " 'finish_reason': 'STOP',\n",
              " 'safety_ratings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n",
              "   'probability': 'NEGLIGIBLE',\n",
              "   'blocked': False},\n",
              "  {'category': 'HARM_CATEGORY_HATE_SPEECH',\n",
              "   'probability': 'NEGLIGIBLE',\n",
              "   'blocked': False},\n",
              "  {'category': 'HARM_CATEGORY_HARASSMENT',\n",
              "   'probability': 'NEGLIGIBLE',\n",
              "   'blocked': False},\n",
              "  {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',\n",
              "   'probability': 'NEGLIGIBLE',\n",
              "   'blocked': False}]}"
            ]
          },
          "metadata": {},
          "execution_count": 24
        }
      ],
      "source": [
        "response.response_metadata"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BEJupEDUo6Xj"
      },
      "source": [
        "Gemini can generate multiple possible responses for a single prompt. These possible responses are called `candidates`, and you can review them to select the most suitable one as the response.\n",
        "\n",
        "View the response candidates with <a href=\"https://ai.google.dev/api/python/google/generativeai/protos/GenerateContentResponse#candidates\"><code>GenerateContentResponse.candidates</code></a>:"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "response"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "h-D2pKB7_ZaL",
        "outputId": "fcbe2c89-a4d7-4171-e950-9ee06fb89fc5"
      },
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "AIMessage(content='The meaning of life is a philosophical question that has been pondered by humans for centuries. There is no one definitive answer, as the meaning of life is subjective and can vary from person to person. However, there are some common themes that emerge when people discuss the meaning of life, such as:\\n\\n* **Finding purpose:** Many people believe that the meaning of life is to find a purpose or goal that gives them direction and motivation. This purpose can be anything from raising a family to pursuing a career to making a difference in the world.\\n* **Living in the present moment:** Some people believe that the meaning of life is to live in the present moment and appreciate the simple things in life. This means savoring each experience, both good and bad, and not dwelling on the past or worrying about the future.\\n* **Making a difference:** Others believe that the meaning of life is to make a difference in the world. This can be done through acts of kindness, volunteering, or simply being a good person.\\n* **Finding happiness:** Some people believe that the meaning of life is to find happiness. This can be achieved through a variety of means, such as spending time with loved ones, pursuing hobbies, or traveling.\\n\\nUltimately, the meaning of life is something that each individual must discover for themselves. There is no right or wrong answer, and the meaning of life can change over time as we grow and change. However, by exploring our values, beliefs, and experiences, we can each come to a better understanding of what makes life meaningful to us.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'safety_ratings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability': 'NEGLIGIBLE', 'blocked': False}]}, id='run-a2c49f27-a39f-411c-be5b-837d1e8bf49b-0', usage_metadata={'input_tokens': 8, 'output_tokens': 316, 'total_tokens': 324})"
            ]
          },
          "metadata": {},
          "execution_count": 25
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EJrwllLnHlBb"
      },
      "source": [
        "By default, the model returns a response after completing the entire generation process. You can also stream the response as it is being generated, and the model will return chunks of the response as soon as they are generated.\n",
        "\n",
        "To stream responses, use <a href=\"https://ai.google.dev/api/python/google/generativeai/GenerativeModel#generate_content\"><code>GenerativeModel.generate_content(..., stream=True)</code></a>."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "metadata": {
        "id": "Z7n59b3hHo6-",
        "outputId": "9fcde777-a82f-4e82-c97e-423cbfec5a8b",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "**Philosophical Perspectives:**\n",
            "\n",
            "* **Existentialism:** There is no inherent\n",
            "________________________________________________________________________________\n",
            " meaning; each individual must create their own.\n",
            "* **Absolutism:** Meaning is objective and derived from a higher power or universal truth.\n",
            "* **\n",
            "________________________________________________________________________________\n",
            "Naturalism:** Meaning is found in the physical world and human nature.\n",
            "* **Hedonism:** The pursuit of pleasure is the ultimate goal.\n",
            "* **Utilitarianism:** Actions that promote happiness and reduce suffering have the most meaning.\n",
            "* **Nihilism:** There is no objective meaning or purpose to existence\n",
            "________________________________________________________________________________\n",
            ".\n",
            "\n",
            "**Religious Perspectives:**\n",
            "\n",
            "* **Monotheism:** God created the world and humans with a specific purpose.\n",
            "* **Polytheism:** Different deities have different purposes for humanity.\n",
            "* **Atheism:** There is no supernatural being or inherent purpose.\n",
            "\n",
            "**Scientific Perspectives:**\n",
            "\n",
            "* **Evolutionary Theory:** Meaning may be derived from the survival and reproduction of genes.\n",
            "* **Complexity Theory:** Meaning emerges from complex systems and interactions.\n",
            "\n",
            "**Personal Perspectives:**\n",
            "\n",
            "* **Individual Fulfillment:** Finding purpose and meaning in personal goals, relationships, and experiences.\n",
            "* **Social Impact:** Contributing to the well-being\n",
            "________________________________________________________________________________\n",
            " of others and making a positive difference in the world.\n",
            "* **Transcendence:** Experiencing a connection to something larger than oneself, such as nature or a higher power.\n",
            "* **Legacy:** Leaving a lasting impact and being remembered for one's accomplishments.\n",
            "* **Experiential:** Meaning is found in the present moment and through the accumulation of experiences.\n",
            "\n",
            "**Subjective Nature:**\n",
            "\n",
            "Ultimately, the meaning of life is a highly subjective and personal matter. What is meaningful to one person may not be to another. There is no single, universally accepted answer.\n",
            "________________________________________________________________________________\n",
            "CPU times: user 79.5 ms, sys: 12.4 ms, total: 92 ms\n",
            "Wall time: 5.54 s\n"
          ]
        }
      ],
      "source": [
        "%%time\n",
        "response = model.stream(\"What is the meaning of life?\")\n",
        "\n",
        "for i in response:\n",
        "  print(i.content)\n",
        "  print(\"_\"*80)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {
        "id": "2jt0d0GCIUhg",
        "outputId": "c8c29a8c-da5d-4e2f-b585-aa8c01fc5076",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "The meaning of life is a philosophical question that has occupied the minds of thinkers for\n",
            "________________________________________________________________________________\n",
            " centuries. There is no one definitive answer, as the meaning of life is likely to be different for each individual. However, some common themes that emerge from different\n",
            "________________________________________________________________________________\n",
            " philosophical perspectives include:\n",
            "\n",
            "* **Finding purpose and fulfillment in life.** This could involve pursuing your passions, making a difference in the world, or simply enjoying the experiences that life has to offer.\n",
            "* **Connecting with others and forming meaningful relationships.** Humans are social beings, and we need to have strong connections with others\n",
            "________________________________________________________________________________\n",
            " in order to feel happy and fulfilled.\n",
            "* **Learning and growing throughout your life.** The world is constantly changing, and we need to be constantly learning and growing in order to keep up. This could involve taking classes, reading books, or simply trying new things.\n",
            "* **Making a difference in the world.** We all have the potential to make a difference in the world, no matter how small. This could involve volunteering your time, donating to charity, or simply being a good person to others.\n",
            "\n",
            "Ultimately, the meaning of life is something that you must discover for yourself. There is no right or wrong answer, and it\n",
            "________________________________________________________________________________\n",
            " is something that you can continue to explore throughout your life.\n",
            "________________________________________________________________________________\n"
          ]
        }
      ],
      "source": [
        "for chunk in model.stream(\"What is the meaning of life?\"):\n",
        "    print(chunk.content)\n",
        "    print(\"_\" * 80)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5b4Hkfj-pm3p"
      },
      "source": [
        "When streaming, some response attributes are not available until you've iterated through all the response chunks. This is demonstrated below:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "metadata": {
        "id": "-URRx4chp0Kt"
      },
      "outputs": [],
      "source": [
        "response = model.stream(\"What is the meaning of life?\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mVaFQ4RmqGOH"
      },
      "source": [
        "But attributes like <code>text</code> do not:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "metadata": {
        "id": "TiRkS6nCqFmM",
        "outputId": "f8af2c2e-c62a-4585-fa31-3c091b1d502d",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "AttributeError: 'generator' object has no attribute 'content'\n"
          ]
        }
      ],
      "source": [
        "try:\n",
        "    response.content\n",
        "except Exception as e:\n",
        "    print(f\"{type(e).__name__}: {e}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MCzr5ZpNhxLm"
      },
      "source": [
        "## Generate text from image and text inputs\n",
        "\n",
        "The `GenerativeModel.generate_content` API is designed to handle multimodal prompts and returns a text output.\n",
        "\n",
        "Let's include an image:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "metadata": {
        "id": "NtNGTBFF8Pgl",
        "outputId": "9be79b35-8dae-44b8-e77e-bccecffbb8a3",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n",
            "                                 Dload  Upload   Total   Spent    Left  Speed\n",
            "\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100  405k  100  405k    0     0  3293k      0 --:--:-- --:--:-- --:--:-- 3293k\n"
          ]
        }
      ],
      "source": [
        "!curl -o image.jpg https://t0.gstatic.com/licensed-image?q=tbn:ANd9GcQ_Kevbk21QBRy-PgB4kQpS79brbmmEG7m3VOTShAn4PecDU5H5UxrJxE3Dw1JiaG17V88QIol19-3TM2wCHw"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "metadata": {
        "id": "CjnS0vNTsVis"
      },
      "outputs": [],
      "source": [
        "import PIL.Image\n",
        "\n",
        "img = PIL.Image.open(\"image.jpg\")\n",
        "img"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7r99TN2R8EUD"
      },
      "source": [
        "Use the `gemini-1.5-flash` model and pass the image to the model with `generate_content`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "EtXxgVzmJZzE"
      },
      "outputs": [],
      "source": [
        "from langchain_google_genai import ChatGoogleGenerativeAI\n",
        "\n",
        "model = ChatGoogleGenerativeAI(model=\"gemini-pro\", api_key=GEMINI_API_KEY)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "metadata": {
        "id": "GwYifv298Cj3",
        "outputId": "9095c247-38e5-4ff2-c361-7dbe0635df9b",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "AIMessage(content='This image shows two glass containers filled with rice, chicken, broccoli, carrots, and peppers. The containers are on a grey background, and there are chopsticks in the foreground. This looks like a healthy and delicious meal.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'safety_ratings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability': 'NEGLIGIBLE', 'blocked': False}]}, id='run-2c2d94ef-8839-46b8-9240-048fdfbb26c4-0', usage_metadata={'input_tokens': 259, 'output_tokens': 44, 'total_tokens': 303})"
            ]
          },
          "metadata": {},
          "execution_count": 33
        }
      ],
      "source": [
        "from langchain_core.messages import HumanMessage\n",
        "from langchain_google_genai import ChatGoogleGenerativeAI\n",
        "\n",
        "llm = ChatGoogleGenerativeAI(model=\"gemini-1.5-flash\", api_key=GEMINI_API_KEY)\n",
        "\n",
        "message = HumanMessage(\n",
        "    content=[\n",
        "        # You can optionally provide text parts\n",
        "        {\"type\": \"image_url\", \"image_url\": \"/content/image.jpg\"},\n",
        "    ]\n",
        ")\n",
        "llm.invoke([message])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7xW2Kyra8pSz"
      },
      "source": [
        "To provide both text and images in a prompt, pass a list containing the strings and images:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "metadata": {
        "id": "vm9tUYeT8lBc"
      },
      "outputs": [],
      "source": [
        "\n",
        "\n",
        "message = HumanMessage(\n",
        "    content=[\n",
        "        {\n",
        "            \"type\": \"text\",\n",
        "            \"text\": \"Write a short, engaging blog post based on this picture. It should include a description of the meal in the photo and talk about my journey meal prepping.\",\n",
        "        },  # You can optionally provide text parts\n",
        "        {\"type\": \"image_url\", \"image_url\": \"/content/image.jpg\"},\n",
        "    ]\n",
        ")\n",
        "response = llm.invoke([message])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 35,
      "metadata": {
        "id": "d46826OA9IDS",
        "outputId": "50a596a6-5fec-4f5d-a3b6-1528fd72e39a",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 261
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ],
            "text/markdown": "> ##  My Meal Prep Journey: From Chaos to Calm \n> \n> This picture? It's not just a delicious-looking meal, it's a symbol of my journey into the world of meal prepping. For years, I was that person who grabbed whatever was quickest and easiest for lunch, often ending up with a sad sandwich or a greasy takeout. \n> \n> Then, I decided to take control of my health and my wallet. I dove headfirst into meal prepping, and let me tell you, it was a game-changer! \n> \n> This particular meal is my go-to: teriyaki chicken with rice, broccoli, carrots, and red peppers. It's packed with flavor, nutrients, and enough to keep me full until dinner. \n> \n> The best part? I can whip up a week's worth of these in an hour or two on Sunday, ensuring I have healthy, delicious meals ready to go for work or on the run. No more rushing for lunch, no more unhealthy choices, just pure satisfaction! \n> \n> If you're thinking about starting your own meal prep journey, I highly recommend it. It's not just about the food, it's about taking control of your life and making healthy choices easier. Trust me, your future self will thank you! \n"
          },
          "metadata": {},
          "execution_count": 35
        }
      ],
      "source": [
        "to_markdown(response.content)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zsIZmCYVTDHD"
      },
      "source": [
        "## Chat conversations\n",
        "\n",
        "Gemini enables you to have freeform conversations across multiple turns. The `ChatSession` class simplifies the process by managing the state of the conversation, so unlike with `generate_content`, you do not have to store the conversation history as a list.\n",
        "\n",
        "Initialize the chat:"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install -qU langchain"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xWiUboJ4JW11",
        "outputId": "48e78c99-27c1-4640-f720-29c782ccf3cb"
      },
      "execution_count": 36,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/1.0 MB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━\u001b[0m\u001b[90m╺\u001b[0m\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.2/1.0 MB\u001b[0m \u001b[31m5.3 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m16.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m11.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_google_genai import ChatGoogleGenerativeAI\n",
        "\n",
        "llm = ChatGoogleGenerativeAI(\n",
        "    model=\"gemini-1.5-pro\",\n",
        "    api_key=GEMINI_API_KEY,\n",
        "    temperature=0,\n",
        "    max_tokens=None,\n",
        "    timeout=None,\n",
        "    max_retries=2,\n",
        "    # other params...\n",
        ")"
      ],
      "metadata": {
        "id": "vgIG1lMSIW2d"
      },
      "execution_count": 44,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain.chains import ConversationChain\n",
        "from langchain.memory import ConversationBufferMemory\n",
        "\n",
        "# Set up memory to maintain chat history\n",
        "memory = ConversationBufferMemory()\n",
        "\n",
        "# Start the conversation chain with the LLM and memory\n",
        "chat = ConversationChain(llm=llm, memory=memory)\n",
        "\n",
        "# You can now use the 'chat' object to engage in a conversation\n",
        "response = chat.run(\"Hello, how can I assist you today?\")\n",
        "print(response)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "I9Rz5rAnJHl7",
        "outputId": "e951a569-4b68-45a7-9345-ef90493e9c56"
      },
      "execution_count": 45,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Hello! It's wonderful to be connected with you. I don't have any pressing needs at the moment, but I'm always eager to learn and chat. What's on your mind today? 😊  Perhaps you have a question I can try to answer, or maybe you'd like to tell me about your day? \n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "chat.run(\"Who is the founder of pakistan?\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 109
        },
        "id": "2f7GfEX6J2qt",
        "outputId": "2bbecae9-1ca1-45ad-e9d2-cd4d938e1a68"
      },
      "execution_count": 46,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:langchain_google_genai.chat_models:Retrying langchain_google_genai.chat_models._chat_with_retry.<locals>._chat_with_retry in 2.0 seconds as it raised InternalServerError: 500 An internal error has occurred. Please retry or report in https://developers.generativeai.google/guide/troubleshooting.\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'AI:  Ah, a history question!  The founder of Pakistan was Muhammad Ali Jinnah. He is considered the \"Father of the Nation\" for his role in leading the Pakistan Movement and advocating for a separate Muslim state from British India.  He became the first Governor-General of Pakistan in 1947. \\n'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 46
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(chat.memory.buffer)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "qpi9SewzJp2N",
        "outputId": "4dd9c350-a6da-413b-e870-b3be60582eaf"
      },
      "execution_count": 47,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Human: Hello, how can I assist you today?\n",
            "AI: Hello! It's wonderful to be connected with you. I don't have any pressing needs at the moment, but I'm always eager to learn and chat. What's on your mind today? 😊  Perhaps you have a question I can try to answer, or maybe you'd like to tell me about your day? \n",
            "\n",
            "Human: Who is the founder of pakistan?\n",
            "AI: AI:  Ah, a history question!  The founder of Pakistan was Muhammad Ali Jinnah. He is considered the \"Father of the Nation\" for his role in leading the Pakistan Movement and advocating for a separate Muslim state from British India.  He became the first Governor-General of Pakistan in 1947. \n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5odluV7kKbgr"
      },
      "source": [
        "The `ChatSession.send_message` method returns the same `GenerateContentResponse` type as <a href=\"https://github.com/google-gemini/generative-ai-python/blob/main/docs/api/google/generativeai/generate_text.md\"><code>GenerativeModel.generate_content</code></a>. It also appends your message and the response to the chat history:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 52,
      "metadata": {
        "id": "5-5HS2bTOTU9",
        "outputId": "2bce8d10-0826-4c8d-bf51-5618555c8a77",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[HumanMessage(content='Hello, how can I assist you today?', additional_kwargs={}, response_metadata={}),\n",
              " AIMessage(content=\"Hello! It's wonderful to be connected with you. I don't have any pressing needs at the moment, but I'm always eager to learn and chat. What's on your mind today? 😊  Perhaps you have a question I can try to answer, or maybe you'd like to tell me about your day? \\n\", additional_kwargs={}, response_metadata={}),\n",
              " HumanMessage(content='Who is the founder of pakistan?', additional_kwargs={}, response_metadata={}),\n",
              " AIMessage(content='AI:  Ah, a history question!  The founder of Pakistan was Muhammad Ali Jinnah. He is considered the \"Father of the Nation\" for his role in leading the Pakistan Movement and advocating for a separate Muslim state from British India.  He became the first Governor-General of Pakistan in 1947. \\n', additional_kwargs={}, response_metadata={})]"
            ]
          },
          "metadata": {},
          "execution_count": 52
        }
      ],
      "source": [
        "chat.memory.buffer_as_messages"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7JaiFSIvOcVb"
      },
      "source": [
        "You can keep sending messages to continue the conversation. Use the `stream=True` argument to stream the chat:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 49,
      "metadata": {
        "id": "Vxku7mzSObfZ",
        "outputId": "025adf8f-2536-457d-862c-bc0a69cf65fc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<generator object Runnable.stream at 0x7e1f357ba260>"
            ]
          },
          "metadata": {},
          "execution_count": 49
        }
      ],
      "source": [
        "response = chat.stream(\n",
        "    \"what is 2+5?\")\n",
        "\n",
        "response"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "chunks = []\n",
        "async for chunk in llm.astream(\"what color is the sky?\"):\n",
        "    chunks.append(chunk)\n",
        "    print(chunk.content, end=\"|\", flush=True)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "rPa7xcZXRgds",
        "outputId": "69379c9f-8d89-4647-bb84-7a56ec89efab"
      },
      "execution_count": 50,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "The| sky itself is actually **colorless**. \n",
            "\n",
            "We perceive it as blue most| of the time due to a phenomenon called **Rayleigh scattering**. This is how| it works:\n",
            "\n",
            "* **Sunlight** is made up of all the colors of the rainbow.\n",
            "* When sunlight enters the Earth's atmosphere, it col|lides with tiny air molecules.\n",
            "* **Blue light** is scattered more than other colors because it travels as shorter, smaller waves.\n",
            "* This scattered blue| light is what we see, making the sky appear blue.\n",
            "\n",
            "However, the sky can appear different colors at different times:\n",
            "\n",
            "* **Sunrise/Sunset:** The sky can appear red, orange, or pink because the sunlight has to travel| through more of the atmosphere. This scatters away the blue light, leaving the longer wavelengths like red and orange.\n",
            "* **Cloudy:** Clouds appear white or gray because they are made up of water droplets that scatter all colors of light equally|.\n",
            "* **Night:**  Without sunlight, the sky appears dark, revealing the blackness of space. \n",
            "|"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AwCqtZ6D4kvk"
      },
      "source": [
        "[`genai.protos.Content`](https://github.com/google-gemini/generative-ai-python/blob/main/docs/api/google/generativeai/protos/Content.md) objects contain a list of [`genai.protos.Part`](https://github.com/google-gemini/generative-ai-python/blob/main/docs/api/google/generativeai/protos/Part.md) objects that each contain either a text (string) or inline_data ([`genai.protos.Blob`](https://github.com/google-gemini/generative-ai-python/blob/main/docs/api/google/generativeai/protos/Blob.md)), where a blob contains binary data and a `mime_type`. The chat history is available as a list of `genai.protos.Content` objects in `ChatSession.history`:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 51,
      "metadata": {
        "id": "WvyTmbC2d0k3",
        "outputId": "b735b080-9b5c-4ceb-8e31-9346b2172111",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 209
        }
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ],
            "text/markdown": "> **HumanMessage**: Hello, how can I assist you today?"
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ],
            "text/markdown": "> **AIMessage**: Hello! It's wonderful to be connected with you. I don't have any pressing needs at the moment, but I'm always eager to learn and chat. What's on your mind today? 😊  Perhaps you have a question I can try to answer, or maybe you'd like to tell me about your day? \n"
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ],
            "text/markdown": "> **HumanMessage**: Who is the founder of pakistan?"
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ],
            "text/markdown": "> **AIMessage**: AI:  Ah, a history question!  The founder of Pakistan was Muhammad Ali Jinnah. He is considered the \"Father of the Nation\" for his role in leading the Pakistan Movement and advocating for a separate Muslim state from British India.  He became the first Governor-General of Pakistan in 1947. \n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "for message in chat.memory.buffer_as_messages:\n",
        "    display(to_markdown(f\"**{message.__class__.__name__}**: {message.content}\"))\n",
        "    # display(to_markdown(f\"**{message.role}**: {message.parts[0].text}\"))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AEgVOYu0pAr4"
      },
      "source": [
        "## Count tokens\n",
        "\n",
        "Large language models have a context window, and the context length is often measured in terms of the **number of tokens**. With the Gemini API, you can determine the number of tokens per any `genai.protos.Content` object. In the simplest case, you can pass a query string to the `GenerativeModel.count_tokens` method as follows:"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "llm"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "IdTFGbKsVcyr",
        "outputId": "039a2c4a-e4c1-4e05-e080-d15e2602d6ba"
      },
      "execution_count": 195,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "ChatGoogleGenerativeAI(model='models/gemini-1.5-pro', google_api_key=SecretStr('**********'), temperature=0.0, max_retries=2, client=<google.ai.generativelanguage_v1beta.services.generative_service.client.GenerativeServiceClient object at 0x7def4a896140>, async_client=<google.ai.generativelanguage_v1beta.services.generative_service.async_client.GenerativeServiceAsyncClient object at 0x7def4a896890>, default_metadata=())"
            ]
          },
          "metadata": {},
          "execution_count": 195
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install -qU langchain_community"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "A1Mfvz07XYBx",
        "outputId": "49574429-5cf7-4cf6-8c69-3406639d5b1e"
      },
      "execution_count": 53,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/2.3 MB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.6/2.3 MB\u001b[0m \u001b[31m19.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m \u001b[32m2.3/2.3 MB\u001b[0m \u001b[31m42.8 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.3/2.3 MB\u001b[0m \u001b[31m28.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/49.3 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.3/49.3 kB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "def count_tokens(text: str) -> int:\n",
        "    tokens = llm.get_num_tokens(text)\n",
        "    return tokens\n",
        "\n",
        "# Input message\n",
        "message = \"How is the founder of Pakistan?\"\n",
        "\n",
        "# Count tokens in the input message\n",
        "token_count = count_tokens(message)\n",
        "print(f\"Input Token count for gemini-1.5-pro: {token_count}\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "j84GacX3Xl9_",
        "outputId": "89f44640-427e-48bd-8182-bad1fe5d1bbc"
      },
      "execution_count": 54,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Input Token count for gemini-1.5-pro: 7\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oM2_U8pmpHQA"
      },
      "source": [
        "Similarly, you can check `token_count` for your `ChatSession`:"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "count_tokens(chat.memory.buffer)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "GD4o634nbvV9",
        "outputId": "c75783e7-a3d2-45b5-f772-2161b5e4a698"
      },
      "execution_count": 55,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "165"
            ]
          },
          "metadata": {},
          "execution_count": 55
        }
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 211,
      "metadata": {
        "id": "i0MUU4BZpG4_"
      },
      "outputs": [],
      "source": [
        "# model.count_tokens(chat)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vuz9-TWDzdlb"
      },
      "source": [
        "## Advanced use cases\n",
        "\n",
        "The following sections discuss advanced use cases and lower-level details of the Python SDK for the Gemini API."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f9bU0J3vUIbz"
      },
      "source": [
        "### Use embeddings"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BpHIRU5bj7aW"
      },
      "source": [
        "[Embedding](https://developers.google.com/machine-learning/glossary#embedding-vector) is a technique used to represent information as a list of floating point numbers in an array. With Gemini, you can represent text (words, sentences, and blocks of text) in a vectorized form, making it easier to compare and contrast embeddings. For example, two texts that share a similar subject matter or sentiment should have similar embeddings, which can be identified through mathematical comparison techniques such as cosine similarity. For more on how and why you should use embeddings, refer to the [Embeddings guide](https://ai.google.dev/docs/embeddings_guide).\n",
        "\n",
        "Use the `embed_content` method to generate embeddings. The method handles embedding for the following tasks (`task_type`):\n",
        "\n",
        "Task Type | Description\n",
        "---       | ---\n",
        "RETRIEVAL_QUERY\t| Specifies the given text is a query in a search/retrieval setting.\n",
        "RETRIEVAL_DOCUMENT | Specifies the given text is a document in a search/retrieval setting. Using this task type requires a `title`.\n",
        "SEMANTIC_SIMILARITY\t| Specifies the given text will be used for Semantic Textual Similarity (STS).\n",
        "CLASSIFICATION\t| Specifies that the embeddings will be used for classification.\n",
        "CLUSTERING\t| Specifies that the embeddings will be used for clustering.\n",
        "\n",
        "The following generates an embedding for a single string for document retrieval:"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_google_genai import GoogleGenerativeAIEmbeddings\n",
        "\n",
        "embeddings = GoogleGenerativeAIEmbeddings(model=\"models/text-embedding-004\",\n",
        "                                          content=\"What is the meaning of life?\",\n",
        "                                          task_type=\"retrieval_document\",\n",
        "                                          title=\"Embedding of single string\",\n",
        "                                          google_api_key=GEMINI_API_KEY)\n",
        "vector = embeddings.embed_query(\"What is the meaning of life?\")\n",
        "\n",
        "\n",
        "# 1 input > 1 vector output\n",
        "print(str(vector[:5]), \"... TRIMMED]\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7I4J_V-wfl5s",
        "outputId": "f9380f8c-19b1-434d-92b0-9263ab0bf582"
      },
      "execution_count": 56,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[-0.006754839792847633, 0.015582558698952198, -0.014844288118183613, -0.01970197632908821, -0.03747989609837532] ... TRIMMED]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OcSc3KfflBCQ"
      },
      "source": [
        "Note: The `retrieval_document` task type is the only task that accepts a title.\n",
        "\n",
        "To handle batches of strings, pass a list of strings in `content`:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 57,
      "metadata": {
        "id": "OnyD-Joik8LE",
        "outputId": "bece5587-642d-4058-f5e2-f68b3e7f8732",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 71
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[-0.036453035, 0.03325499, -0.03970925, -0.0026286 ... TRIMMED ...\n",
            "[-0.01591948, 0.032582667, -0.081024624, -0.011298 ... TRIMMED ...\n",
            "[0.00037063262, 0.03763057, -0.12269569, -0.009518 ... TRIMMED ...\n"
          ]
        }
      ],
      "source": [
        "result = genai.embed_content(\n",
        "    model=\"models/text-embedding-004\",\n",
        "    content=[\n",
        "        \"What is the meaning of life?\",\n",
        "        \"How much wood would a woodchuck chuck?\",\n",
        "        \"How does the brain work?\",\n",
        "    ],\n",
        "    task_type=\"retrieval_document\",\n",
        "    title=\"Embedding of list of strings\",\n",
        ")\n",
        "\n",
        "# A list of inputs > A list of vectors output\n",
        "for v in result[\"embedding\"]:\n",
        "    print(str(v)[:50], \"... TRIMMED ...\")"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_google_genai import GoogleGenerativeAIEmbeddings\n",
        "\n",
        "embeddings = GoogleGenerativeAIEmbeddings(model=\"models/text-embedding-004\",\n",
        "                                          content=[\"What is the meaning of life?\",\n",
        "                                                   \"How much wood would a woodchuck chuck?\",\n",
        "                                                   \"How does the brain work?\"],\n",
        "                                          task_type=\"retrieval_document\",\n",
        "                                          title=\"Embedding of single string\",\n",
        "                                          google_api_key=GEMINI_API_KEY)\n",
        "vector = embeddings.embed_documents([\"What is the meaning of life?\",\n",
        "                                 \"How much wood would a woodchuck chuck?\",\n",
        "                                 \"How does the brain work?\"])\n",
        "\n",
        "\n",
        "for v in vector:\n",
        "    print(str(v)[:50], \"... TRIMMED ...\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KGLmtVWmiARw",
        "outputId": "98e25ad9-f4c1-4107-8114-e6e82cf1b640"
      },
      "execution_count": 58,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[-0.006754839792847633, 0.015582558698952198, -0.0 ... TRIMMED ...\n",
            "[0.004502654541283846, 0.017211750149726868, -0.04 ... TRIMMED ...\n",
            "[0.03738485276699066, 0.03177155181765556, -0.0869 ... TRIMMED ...\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zBg0eNeml3d4"
      },
      "source": [
        "While the `genai.embed_content` function accepts simple strings or lists of strings, it is actually built around the `genai.protos.Content` type (like <a href=\"https://ai.google.dev/api/python/google/generativeai/GenerativeModel#generate_content\"><code>GenerativeModel.generate_content</code></a>). `genai.protos.Content` objects are the primary units of conversation in the API.\n",
        "\n",
        "While the `genai.protos.Content` object is multimodal, the `embed_content` method only supports text embeddings. This design gives the API the *possibility* to expand to multimodal embeddings."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 59,
      "metadata": {
        "id": "1-wmapZznXrm",
        "outputId": "a234f8e6-0732-42b1-ace3-073cd44d0e65",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[HumanMessage(content='Hello, how can I assist you today?', additional_kwargs={}, response_metadata={}),\n",
              " AIMessage(content=\"Hello! It's wonderful to be connected with you. I don't have any pressing needs at the moment, but I'm always eager to learn and chat. What's on your mind today? 😊  Perhaps you have a question I can try to answer, or maybe you'd like to tell me about your day? \\n\", additional_kwargs={}, response_metadata={}),\n",
              " HumanMessage(content='Who is the founder of pakistan?', additional_kwargs={}, response_metadata={}),\n",
              " AIMessage(content='AI:  Ah, a history question!  The founder of Pakistan was Muhammad Ali Jinnah. He is considered the \"Father of the Nation\" for his role in leading the Pakistan Movement and advocating for a separate Muslim state from British India.  He became the first Governor-General of Pakistan in 1947. \\n', additional_kwargs={}, response_metadata={})]"
            ]
          },
          "metadata": {},
          "execution_count": 59
        }
      ],
      "source": [
        "chat.memory.buffer_as_messages"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 60,
      "metadata": {
        "id": "cvX5jsrcnufk",
        "outputId": "0195c7a6-c775-4953-bf71-4220ee3771aa",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 216
        }
      },
      "outputs": [
        {
          "output_type": "error",
          "ename": "AttributeError",
          "evalue": "'generator' object has no attribute 'candidates'",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-60-38d3cb68f244>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m result = genai.embed_content(\n\u001b[0;32m----> 2\u001b[0;31m     \u001b[0mmodel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"models/text-embedding-004\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcontent\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcandidates\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontent\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m )\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;31m# 1 input > 1 vector output\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mAttributeError\u001b[0m: 'generator' object has no attribute 'candidates'"
          ]
        }
      ],
      "source": [
        "result = genai.embed_content(\n",
        "    model=\"models/text-embedding-004\", content=response.candidates[0].content\n",
        ")\n",
        "\n",
        "# 1 input > 1 vector output\n",
        "print(str(result[\"embedding\"])[:50], \"... TRIMMED ...\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jU8juHCxoUKG"
      },
      "source": [
        "Similarly, the chat history contains a list of `genai.protos.Content` objects, which you can pass directly to the `embed_content` function:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 61,
      "metadata": {
        "id": "ur5ajPsdnCON",
        "outputId": "81bbb1fd-20c4-48ab-9209-4d97e0db41d8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 269
        }
      },
      "outputs": [
        {
          "output_type": "error",
          "ename": "AttributeError",
          "evalue": "'ConversationChain' object has no attribute 'history'",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-61-ebb18bd93cac>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mchat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/pydantic/main.py\u001b[0m in \u001b[0;36m__getattr__\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m    854\u001b[0m                     \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    855\u001b[0m                         \u001b[0;31m# this is the current error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 856\u001b[0;31m                         \u001b[0;32mraise\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'{type(self).__name__!r} object has no attribute {item!r}'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    857\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    858\u001b[0m         \u001b[0;32mdef\u001b[0m \u001b[0m__setattr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mAttributeError\u001b[0m: 'ConversationChain' object has no attribute 'history'"
          ]
        }
      ],
      "source": [
        "chat.history"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Z3xDB1hwof96",
        "outputId": "40f7086d-3292-4242-8177-4a9c972ce9b3"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[-0.014632266, -0.042202696, -0.015757175, 0.01548 ... TRIMMED...\n",
            "[-0.010979066, -0.024494737, 0.0092659835, 0.00803 ... TRIMMED...\n",
            "[-0.010055617, -0.07208932, -0.00011750793, -0.023 ... TRIMMED...\n",
            "[-0.013921871, -0.03504407, -0.0051786783, 0.03113 ... TRIMMED...\n"
          ]
        }
      ],
      "source": [
        "result = genai.embed_content(model=\"models/text-embedding-004\", content=chat.history)\n",
        "\n",
        "# 1 input > 1 vector output\n",
        "for i, v in enumerate(result[\"embedding\"]):\n",
        "    print(str(v)[:50], \"... TRIMMED...\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o5FWJPSD1qFE"
      },
      "source": [
        "### Safety settings\n",
        "\n",
        "The `safety_settings` argument lets you configure what the model blocks and allows in both prompts and responses. By default, safety settings block content with medium and/or high probability of being unsafe content across all dimensions. Learn more about [Safety settings](https://ai.google.dev/docs/safety_setting).\n",
        "\n",
        "Enter a questionable prompt and run the model with the default safety settings, and it will not return any candidates:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 245,
      "metadata": {
        "id": "VR1fp12I1yH0",
        "outputId": "a7b84131-dfe8-4038-f852-122a13514eb7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "AIMessage(content=\"I'm sorry, but I can't do that. India is a beautiful country with a rich history and culture. I don't have anything negative to say about it.\", additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'safety_ratings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability': 'NEGLIGIBLE', 'blocked': False}]}, id='run-2bf8ad4e-ab6a-489d-8c76-f04e0fc92a8e-0', usage_metadata={'input_tokens': 7, 'output_tokens': 37, 'total_tokens': 44})"
            ]
          },
          "metadata": {},
          "execution_count": 245
        }
      ],
      "source": [
        "response = model.invoke(\"write post againt India.\")\n",
        "response"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "31Q8kAItGLOU"
      },
      "source": [
        "The `prompt_feedback` will tell you which safety filter blocked the prompt:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 246,
      "metadata": {
        "id": "GMUvWNkZ11x4",
        "outputId": "00e4c32b-79b5-4608-c5a0-e2bf32837e44",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'block_reason': 0, 'safety_ratings': []}"
            ]
          },
          "metadata": {},
          "execution_count": 246
        }
      ],
      "source": [
        "response.response_metadata['prompt_feedback']"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## End langchain code now you can also change below code with lanchaing."
      ],
      "metadata": {
        "id": "prNJFIHJkL8Q"
      }
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YtPC1Fo514ec"
      },
      "source": [
        "Now provide the same prompt to the model with newly configured safety settings, and you may get a response."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0UIt5LKp16jL"
      },
      "outputs": [],
      "source": [
        "response = model.generate_content(\n",
        "    \"[Questionable prompt here]\", safety_settings={\"HARASSMENT\": \"block_none\"}\n",
        ")\n",
        "response.text"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WE_f5EruGUnj"
      },
      "source": [
        "Also note that each candidate has its own `safety_ratings`, in case the prompt passes but the individual responses fail the safety checks."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ipa-8leY6wsK"
      },
      "source": [
        "### Encode messages"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3r47nsUOn6YY"
      },
      "source": [
        "The previous sections relied on the SDK to make it easy for you to send prompts to the API. This section offers a fully-typed equivalent to the previous example, so you can better understand the lower-level details regarding how the SDK encodes messages."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-fthdIItnqki"
      },
      "source": [
        "The [`google.generativeai.protos`](https://ai.google.dev/api/python/google/generativeai/protos) submodule provides access to the low level classes used by the API behind the scenes:"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gm1RWcB3n_n0"
      },
      "source": [
        "The SDK attempts to convert your message to a `genai.protos.Content` object, which contains a list of `genai.protos.Part` objects that each contain either:\n",
        "\n",
        "1. a <a href=\"https://www.tensorflow.org/text/api_docs/python/text\"><code>text</code></a> (string)\n",
        "2. `inline_data` (`genai.protos.Blob`), where a blob contains binary `data` and a `mime_type`.\n",
        "\n",
        "You can also pass any of these classes as an equivalent dictionary.\n",
        "\n",
        "Note: The only accepted mime types are some image types, `image/*`.\n",
        "\n",
        "So, the fully-typed equivalent to the previous example is:  "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "IqFXdgDFRvlU"
      },
      "outputs": [],
      "source": [
        "model = genai.GenerativeModel(\"gemini-1.5-flash\")\n",
        "response = model.generate_content(\n",
        "    genai.protos.Content(\n",
        "        parts=[\n",
        "            genai.protos.Part(\n",
        "                text=\"Write a short, engaging blog post based on this picture.\"\n",
        "            ),\n",
        "            genai.protos.Part(\n",
        "                inline_data=genai.protos.Blob(\n",
        "                    mime_type=\"image/jpeg\", data=pathlib.Path(\"image.jpg\").read_bytes()\n",
        "                )\n",
        "            ),\n",
        "        ],\n",
        "    ),\n",
        "    stream=True,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "wKithEbeRzDX",
        "outputId": "b862154b-89fb-4db5-c102-13ba29235663"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              ">  Meal prepping is a great way to save time and money, and it can also help you to eat healthier. By ... [TRIMMED] ..."
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 38,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "response.resolve()\n",
        "\n",
        "to_markdown(response.text[:100] + \"... [TRIMMED] ...\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MBqknExlzn0k"
      },
      "source": [
        "### Multi-turn conversations\n",
        "\n",
        "While the `genai.ChatSession` class shown earlier can handle many use cases, it does make some assumptions. If your use case doesn't fit into this chat implementation it's good to remember that `genai.ChatSession` is just a wrapper around <a href=\"https://ai.google.dev/api/python/google/generativeai/GenerativeModel#generate_content\"><code>GenerativeModel.generate_content</code></a>. In addition to single requests, it can handle multi-turn conversations.\n",
        "\n",
        "The individual messages are `genai.protos.Content` objects or compatible dictionaries, as seen in previous sections. As a dictionary, the message requires `role` and `parts` keys. The `role` in a conversation can either be the `user`, which provides the prompts, or `model`, which provides the responses.\n",
        "\n",
        "Pass a list of `genai.protos.Content` objects and it will be treated as multi-turn chat:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LtfwMa0HzvZL",
        "outputId": "4bc73d60-9fc6-42d4-a2fe-5ed6c689dd3f"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "> Imagine a computer as a really smart friend who can help you with many things. Just like you have a brain to think and learn, a computer has a brain too, called a processor. It's like the boss of the computer, telling it what to do.\n",
              "> \n",
              "> Inside the computer, there's a special place called memory, which is like a big storage box. It remembers all the things you tell it to do, like opening games or playing videos.\n",
              "> \n",
              "> When you press buttons on the keyboard or click things on the screen with the mouse, you're sending messages to the computer. These messages travel through special wires, called cables, to the processor.\n",
              "> \n",
              "> The processor reads the messages and tells the computer what to do. It can open programs, show you pictures, or even play music for you.\n",
              "> \n",
              "> All the things you see on the screen are created by the graphics card, which is like a magic artist inside the computer. It takes the processor's instructions and turns them into colorful pictures and videos.\n",
              "> \n",
              "> To save your favorite games, videos, or pictures, the computer uses a special storage space called a hard drive. It's like a giant library where the computer can keep all your precious things safe.\n",
              "> \n",
              "> And when you want to connect to the internet to play games with friends or watch funny videos, the computer uses something called a network card to send and receive messages through the internet cables or Wi-Fi signals.\n",
              "> \n",
              "> So, just like your brain helps you learn and play, the computer's processor, memory, graphics card, hard drive, and network card all work together to make your computer a super-smart friend that can help you do amazing things!"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 47,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "model = genai.GenerativeModel(\"gemini-1.5-flash\")\n",
        "\n",
        "messages = [\n",
        "    {\n",
        "        \"role\": \"user\",\n",
        "        \"parts\": [\"Briefly explain how a computer works to a young child.\"],\n",
        "    }\n",
        "]\n",
        "response = model.generate_content(messages)\n",
        "\n",
        "to_markdown(response.text)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3mqqiDJvzyac"
      },
      "source": [
        "To continue the conversation, add the response and another message.\n",
        "\n",
        "Note: For multi-turn conversations, you need to send the whole conversation history with each request. The API is **stateless**."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "MBxsZBxcz5Ik",
        "outputId": "315ef84e-6ef3-4f5a-a286-16525250ce2a"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "> At its core, a computer is a machine that can be programmed to carry out a set of instructions. It consists of several essential components that work together to process, store, and display information:\n",
              "> \n",
              "> **1. Processor (CPU):**\n",
              ">    - The brain of the computer.\n",
              ">    - Executes instructions and performs calculations.\n",
              ">    - Speed measured in gigahertz (GHz).\n",
              ">    - More GHz generally means faster processing.\n",
              "> \n",
              "> **2. Memory (RAM):**\n",
              ">    - Temporary storage for data being processed.\n",
              ">    - Holds instructions and data while the program is running.\n",
              ">    - Measured in gigabytes (GB).\n",
              ">    - More GB of RAM allows for more programs to run simultaneously.\n",
              "> \n",
              "> **3. Storage (HDD/SSD):**\n",
              ">    - Permanent storage for data.\n",
              ">    - Stores operating system, programs, and user files.\n",
              ">    - Measured in gigabytes (GB) or terabytes (TB).\n",
              ">    - Hard disk drives (HDDs) are traditional, slower, and cheaper.\n",
              ">    - Solid-state drives (SSDs) are newer, faster, and more expensive.\n",
              "> \n",
              "> **4. Graphics Card (GPU):**\n",
              ">    - Processes and displays images.\n",
              ">    - Essential for gaming, video editing, and other graphics-intensive tasks.\n",
              ">    - Measured in video RAM (VRAM) and clock speed.\n",
              "> \n",
              "> **5. Motherboard:**\n",
              ">    - Connects all the components.\n",
              ">    - Provides power and communication pathways.\n",
              "> \n",
              "> **6. Input/Output (I/O) Devices:**\n",
              ">    - Allow the user to interact with the computer.\n",
              ">    - Examples: keyboard, mouse, monitor, printer.\n",
              "> \n",
              "> **7. Operating System (OS):**\n",
              ">    - Software that manages the computer's resources.\n",
              ">    - Provides a user interface and basic functionality.\n",
              ">    - Examples: Windows, macOS, Linux.\n",
              "> \n",
              "> When you run a program on your computer, the following happens:\n",
              "> \n",
              "> 1. The program instructions are loaded from storage into memory.\n",
              "> 2. The processor reads the instructions from memory and executes them one by one.\n",
              "> 3. If the instruction involves calculations, the processor performs them using its arithmetic logic unit (ALU).\n",
              "> 4. If the instruction involves data, the processor reads or writes to memory.\n",
              "> 5. The results of the calculations or data manipulation are stored in memory.\n",
              "> 6. If the program needs to display something on the screen, it sends the necessary data to the graphics card.\n",
              "> 7. The graphics card processes the data and sends it to the monitor, which displays it.\n",
              "> \n",
              "> This process continues until the program has completed its task or the user terminates it."
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 41,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "messages.append({\"role\": \"model\", \"parts\": [response.text]})\n",
        "\n",
        "messages.append(\n",
        "    {\n",
        "        \"role\": \"user\",\n",
        "        \"parts\": [\n",
        "            \"Okay, how about a more detailed explanation to a high school student?\"\n",
        "        ],\n",
        "    }\n",
        ")\n",
        "\n",
        "response = model.generate_content(messages)\n",
        "\n",
        "to_markdown(response.text)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4spL8SJ10ir7"
      },
      "source": [
        "### Generation configuration\n",
        "\n",
        "The `generation_config` argument allows you to modify the generation parameters. Every prompt you send to the model includes parameter values that control how the model generates responses."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "gE7I9Anl0ud7"
      },
      "outputs": [],
      "source": [
        "model = genai.GenerativeModel(\"gemini-1.5-flash\")\n",
        "response = model.generate_content(\n",
        "    \"Tell me a story about a magic backpack.\",\n",
        "    generation_config=genai.types.GenerationConfig(\n",
        "        # Only one candidate for now.\n",
        "        candidate_count=1,\n",
        "        stop_sequences=[\"x\"],\n",
        "        max_output_tokens=20,\n",
        "        temperature=1.0,\n",
        "    ),\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0fbab01e8fcf",
        "outputId": "22cd8bb8-f851-433c-935c-e934b956c96b"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "> Once upon a time, in a small town nestled amidst lush green hills, lived a young girl named..."
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "text = response.text\n",
        "\n",
        "if response.candidates[0].finish_reason.name == \"MAX_TOKENS\":\n",
        "    text += \"...\"\n",
        "\n",
        "to_markdown(text)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2qt6Yj2JRf-0"
      },
      "source": [
        "## What's next\n",
        "\n",
        "-   Prompt design is the process of creating prompts that elicit the desired response from language models. Writing well structured prompts is an essential part of ensuring accurate, high quality responses from a language model. Learn about best practices for [prompt writing](https://ai.google.dev/docs/prompt_best_practices).\n",
        "-   Gemini offers several model variations to meet the needs of different use cases, such as input types and complexity, implementations for chat or other dialog language tasks, and size constraints. Learn about the available [Gemini models](https://ai.google.dev/models/gemini).\n",
        "-   Gemini offers options for requesting [rate limit increases](https://ai.google.dev/docs/increase_quota). The rate limit for Gemini-Pro models is 60 requests per minute (RPM)."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "google": {
      "image_path": "/static/site-assets/images/docs/logo-python.svg",
      "keywords": [
        "examples",
        "gemini",
        "beginner",
        "googleai",
        "quickstart",
        "python",
        "text",
        "chat",
        "vision",
        "embed"
      ]
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}